home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir43 / perldoss.zip / MSDOS.C < prev    next >
C/C++ Source or Header  |  1991-12-25  |  6KB  |  285 lines

  1. /* $RCSfile: msdos.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:37 $
  2.  *
  3.  *    (C) Copyright 1989, 1990 Diomidis Spinellis.
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    msdos.c,v $
  9.  * Revision 4.0.1.1  91/06/07  11:22:37  lwall
  10.  * patch4: new copyright notice
  11.  *
  12.  * Revision 4.0  91/03/20  01:34:46  lwall
  13.  * 4.0 baseline.
  14.  *
  15.  * Revision 3.0.1.1  90/03/27  16:10:41  lwall
  16.  * patch16: MSDOS support
  17.  *
  18.  * Revision 1.1  90/03/18  20:32:01  dds
  19.  * Initial revision
  20.  *
  21.  */
  22.  
  23.  
  24. /*
  25.  * Various Unix compatibility functions for MS-DOS.
  26.  */
  27.  
  28.  
  29. #include "EXTERN.h"
  30. #include "perl.h"
  31.  
  32.  
  33. #include <dos.h>
  34. #include <process.h>
  35.  
  36. extern unsigned _stklen = 32768U;
  37. #ifdef __OVERLAY__
  38. unsigned _ovrbuffer = 0x2000;
  39. #endif
  40.  
  41. /*
  42.  * Interface to the MS-DOS ioctl system call.
  43.  * The function is encoded as follows:
  44.  * The lowest nibble of the function code goes to AL
  45.  * The two middle nibbles go to CL
  46.  * The high nibble goes to CH
  47.  *
  48.  * The return code is -1 in the case of an error and if successful
  49.  * for functions AL = 00, 09, 0a the value of the register DX
  50.  * for functions AL = 02 - 08, 0e the value of the register AX
  51.  * for functions AL = 01, 0b - 0f the number 0
  52.  *
  53.  * Notice that this restricts the ioctl subcodes stored in AL to 00-0f
  54.  * In the Ralf Borwn interrupt list 90.1 there are no subcodes above AL=0f
  55.  * so we are ok.
  56.  * Furthermore CH is also restriced in the same area.  Where CH is used as a
  57.  * code it always is between 00-0f.  In the case where it forms a count
  58.  * together with CL we arbitrarily set the highest count limit to 4095.  It
  59.  * sounds reasonable for an ioctl.
  60.  * The other alternative would have been to use the pointer argument to
  61.  * point the the values of CX.  The problem with this approach is that
  62.  * of accessing wild regions when DX is used as a number and not as a
  63.  * pointer.
  64.  */
  65. int
  66. ioctl(int handle, unsigned int function, char *data)
  67. {
  68.     union REGS      srv;
  69.     struct SREGS    segregs;
  70.  
  71.  
  72.     srv.h.ah = 0x44;
  73.     srv.h.al = (unsigned char)(function & 0x0F);
  74.     srv.x.bx = handle;
  75.     srv.x.cx = function >> 4;
  76.     segread(&segregs);
  77. #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  78.     segregs.ds = FP_SEG(data);
  79.     srv.x.dx = FP_OFF(data);
  80. #else
  81.     srv.x.dx = (unsigned int) data;
  82. #endif
  83.     intdosx(&srv, &srv, &segregs);
  84.     if (srv.x.cflag & 1) {
  85.         switch(srv.x.ax ){
  86.         case 1:
  87.             errno = EINVAL;
  88.             break;
  89.         case 2:
  90.         case 3:
  91.             errno = ENOENT;
  92.             break;
  93.         case 4:
  94.             errno = EMFILE;
  95.             break;
  96.         case 5:
  97.             errno = EPERM;
  98.             break;
  99.         case 6:
  100.             errno = EBADF;
  101.             break;
  102.         case 8:
  103.             errno = ENOMEM;
  104.             break;
  105.         case 0xc:
  106.         case 0xd:
  107.         case 0xf:
  108.             errno = EINVAL;
  109.             break;
  110.         case 0x11:
  111.             errno = EXDEV;
  112.             break;
  113.         case 0x12:
  114.             errno = ENFILE;
  115.             break;
  116.         default:
  117.             errno = EZERO;
  118.             break;
  119.         }
  120.         return -1;
  121.     } else {
  122.         switch (function & 0xf) {
  123.         case 0: case 9: case 0xa:
  124.             return srv.x.dx;
  125.         case 2: case 3: case 4: case 5:
  126.         case 6: case 7: case 8: case 0xe:
  127.             return srv.x.ax;
  128.         case 1: case 0xb: case 0xc: case 0xd:
  129.         case 0xf:
  130.         default:
  131.             return 0;
  132.         }
  133.     }
  134. }
  135.  
  136.  
  137.  
  138.  
  139. /*
  140.  * Sleep function.
  141.  */
  142. void
  143. sleep(unsigned len)
  144. {
  145.     time_t end;
  146.  
  147.  
  148.     end = time((time_t *)0) + len;
  149.     while (time((time_t *)0) < end)
  150.         ;
  151. }
  152.  
  153.  
  154. /*
  155.  * Just pretend that everyone is a superuser
  156.  */
  157. #define ROOT_UID    0
  158. #define ROOT_GID    0
  159. int
  160. getuid(void)
  161. {
  162.     return ROOT_UID;
  163. }
  164.  
  165.  
  166. int
  167. geteuid(void)
  168. {
  169.     return ROOT_UID;
  170. }
  171.  
  172.  
  173. int
  174. getgid(void)
  175. {
  176.     return ROOT_GID;
  177. }
  178.  
  179.  
  180. int
  181. getegid(void)
  182. {
  183.     return ROOT_GID;
  184. }
  185.  
  186.  
  187. int
  188. setuid(int uid)
  189. { return (uid==ROOT_UID?0:-1); }
  190.  
  191.  
  192. int
  193. setgid(int gid)
  194. { return (gid==ROOT_GID?0:-1); }
  195.  
  196.  
  197. /*
  198.  * The following code is based on the do_exec and do_aexec functions
  199.  * in file doio.c
  200.  */
  201. int
  202. do_aspawn(really,arglast)
  203. STR *really;
  204. int *arglast;
  205. {
  206.     register STR **st = stack->ary_array;
  207.     register int sp = arglast[1];
  208.     register int items = arglast[2] - sp;
  209.     register char **a;
  210.     char **argv;
  211.     char *tmps;
  212.     int status;
  213.  
  214.  
  215.     if (items) {
  216.     New(1101,argv, items+1, char*);
  217.     a = argv;
  218.     for (st += ++sp; items > 0; items--,st++) {
  219.         if (*st)
  220.         *a++ = str_get(*st);
  221.         else
  222.         *a++ = "";
  223.     }
  224.     *a = Nullch;
  225.     if (really && *(tmps = str_get(really)))
  226.         status = xspawnvp(P_WAIT,tmps,argv);
  227.     else
  228.         status = xspawnvp(P_WAIT,argv[0],argv);
  229.     Safefree(argv);
  230.     }
  231.     return status;
  232. }
  233.  
  234.  
  235.  
  236.  
  237. int
  238. do_spawn(cmd)
  239. char *cmd;
  240. {
  241.     register char **a;
  242.     register char *s;
  243.     char **argv;
  244.     char flags[10];
  245.     int status;
  246.     char *shell, *cmd2;
  247.  
  248.  
  249.     /* save an extra exec if possible */
  250.     if ((shell = getenv("COMSPEC")) == 0)
  251.     shell = "\\command.com";
  252.  
  253.  
  254.     /* see if there are shell metacharacters in it */
  255.     if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|'))
  256.       doshell:
  257.         return xspawnl(P_WAIT,shell,shell,"/c",cmd,(char*)0);
  258.  
  259.  
  260.     New(1102,argv, strlen(cmd) / 2 + 2, char*);
  261.  
  262.  
  263.     New(1103,cmd2, strlen(cmd) + 1, char);
  264.     strcpy(cmd2, cmd);
  265.     a = argv;
  266.     for (s = cmd2; *s;) {
  267.     while (*s && isspace(*s)) s++;
  268.     if (*s)
  269.         *(a++) = s;
  270.     while (*s && !isspace(*s)) s++;
  271.     if (*s)
  272.         *s++ = '\0';
  273.     }
  274.     *a = Nullch;
  275.     if (argv[0])
  276.     if ((status = xspawnvp(P_WAIT,argv[0],argv)) == -1) {
  277.         Safefree(argv);
  278.         Safefree(cmd2);
  279.         goto doshell;
  280.     }
  281.     Safefree(cmd2);
  282.     Safefree(argv);
  283.     return status;
  284. }
  285.